﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.IO;

namespace NetDXY
{
    public partial class InfoFrm : NetDXY.BaseFrm
    {
        private string HId, ZId, KId, sDate, sMan;

        private decimal dYJD, dYWD, dYGD, dSheZhiQ, dSheZhiF, dTestQ, dTestF, dTestH;

        
        private Int16 iFlag;
        private DateTime dtStart, dtEnd;

        public string SMan
        {
            get { return sMan; }
            set { sMan = value; }
        }

        public string SDate
        {
            get { return sDate; }
            set { sDate = value; }
        }

        public string KID
        {
            get { return KId; }
            set { KId = value; }
        }

        public string ZID
        {
            get { return ZId; }
            set { ZId = value; }
        }

        public string HID
        {
            get { return HId; }
            set { HId = value; }
        }
       

        public decimal YGD
        {
            get { return dYGD; }
            set { dYGD = value; }
        }

        public decimal YWD
        {
            get { return dYWD; }
            set { dYWD = value; }
        }

        public decimal YJD
        {
            get { return dYJD; }
            set { dYJD = value; }
        }

        public decimal SheZhiF
        {
            get { return dSheZhiF; }
            set { dSheZhiF = value; }
        }

        public decimal SheZhiQ
        {
            get { return dSheZhiQ; }
            set { dSheZhiQ = value; }
        }

        delegate void SetTimerEnableCallBack(System.Windows.Forms.Timer t, bool flag);
        SetTimerEnableCallBack SetTimerEnable;
        void SetTimerEnable1(System.Windows.Forms.Timer t, bool flag)
        {
            t.Enabled = flag;
        }


        public InfoFrm()
        {
            iFlag = 1; //处于发送参数状态.
            this.Location = new Point(0,0);
            InitializeComponent();
            SetTimerEnable = new SetTimerEnableCallBack(SetTimerEnable1);
        }

        //保存数据到文本文件
        private void StartBtn_Click(object sender, EventArgs e)
        {            
            //string strPath = System.Environment.GetFolderPath(Environment.SpecialFolder.Programs) + @"\Data.txt";
            string assembly = System.Reflection.Assembly.GetExecutingAssembly().GetName().CodeBase;
            string currentFolderPath = System.IO.Path.GetDirectoryName(assembly);
            string strPath = currentFolderPath.Substring(6, currentFolderPath.Length - 7) + @"\Data.txt";
            //string strPath = currentFolderPath  + @"\Data.txt";
            MessageBox.Show(strPath);
            if (!File.Exists(strPath))
            {   
                
                //创建要写入的文件
                using (StreamWriter sw = File.CreateText(strPath))
                {
                    sw.WriteLine("Hello");
                    //sw.WriteLine("And");
                    //sw.WriteLine("Welcome");
                }
            }
            else
            {
                //追加数据
                using (StreamWriter sw = File.AppendText(strPath))
                {
                    sw.WriteLine("This");
                    sw.WriteLine("is Extra");
                    sw.WriteLine("Text");
                }
            }

            Close();
        }

        //发送位置信息
        private void SendPosition()
        {
            Byte[] Data = new Byte[17];
            Data[0] = 0x55;
            Data[1] = 0xAA;
            Data[2] = 0x00; //参数标志，0是发送位置信息，1是发送寻北命令
            //Data[17] = (Byte)'\0';
            //组装位置数据
            UInt32 uJD, uWD, uH;
            uJD = (UInt32)(dYJD * 1000000);
            uWD = (UInt32)(dYWD * 1000000);
            uH = (UInt32)(dYGD * 100);

            Data[3] = (Byte)(uJD & 0x000000FF);
            Data[4] = (Byte)((uJD >> 8) & 0x000000FF);
            Data[5] = (Byte)((uJD >> 16) & 0x000000FF);
            Data[6] = (Byte)((uJD >> 24) & 0x000000FF);

            Data[7] = (Byte)(uWD & 0x000000FF);
            Data[8] = (Byte)((uWD >> 8) & 0x000000FF);
            Data[9] = (Byte)((uWD >> 16) & 0x000000FF);
            Data[10] = (Byte)((uWD >> 24) & 0x000000FF);


            Data[11] = (Byte)(uH & 0x000000FF);
            Data[12] = (Byte)((uH >> 8) & 0x000000FF);
            Data[13] = (Byte)((uH >> 16) & 0x000000FF);
            Data[14] = (Byte)((uH >> 24) & 0x000000FF);
            
            serialPort.Write(Data, 0, 17);
            iFlag = 1;
            //1为发送位置信息，2为接收到位置信息返回，3 发送寻北信息，4 接收寻北信息返回
        }

        //发送寻北命令
        private void SendSearchNorth()
        {
            Byte[] Data = new Byte[17];
            Data[0] = 0x55;
            Data[1] = 0xAA;
            Data[2] = 0x01; //参数标志，0是发送位置信息，1是发送寻北命令
            //Data[17] = (Byte)'\0';
            //组装位置数据            
            serialPort.Write(Data, 0, 17);
            iFlag = 3; //1为发送位置信息，2为接收到位置信息返回，3 发送寻北信息，4 接收寻北信息返回
        }

        /*检查返回的数据，返回值作为判断
        iFlag = 1为发送位置信息，2为接收到位置信息返回，3 发送寻北信息，4 接收寻北信息返回            
                  
          
        */
        private int CheckData(Byte[] Data)
        {
            UInt16 iFangWei, iQingJiao, iGunDong;//这三个值等于9990时，99.9度

            iFangWei = Data[4];
            iFangWei = (UInt16)((UInt16)(iFangWei << 8) + (UInt16)Data[3]);

            iQingJiao = Data[6];
            iQingJiao = (UInt16)((UInt16)(iQingJiao << 8) + (UInt16)Data[5]);

            iGunDong = Data[8];
            iGunDong = (UInt16)((UInt16)(iGunDong << 8) + (UInt16)Data[7]);

            //处于发送位置信息状态
            if (iFlag == 1)
            {
                if ((iFangWei == 9990) && (iQingJiao == 9990) && (iGunDong == 9990))//位置信息发送成功，可以发送寻北指令
                { 
                    iFlag = 2; //参数发送成功，更改到 接收到位置信息状态。
                    this.Invoke(SetTimerEnable,tmParam, false);//停止发送参数定时器                    
                    return 1; //返回一代表位置信心发送成功。
                }
                else
                {
                    //iFlag = 1; //处于发送位置信息状态。
                    return 0; //代表位置信息发送失败。
                }
            }

            UInt32 iTX, iTY, iTZ, iGX, iGY, iGZ;
            Byte bFlag = Data[2];

            iTX = (UInt32)(Data[12]*256*256*256+Data[11]*256*256+Data[10]*256+Data[9]);
            iTY = (UInt32)(Data[16]*256*256*256+Data[15]*256*256+Data[14]*256+Data[13]);
            iTZ = (UInt32)(Data[20]*256*256*256+Data[19]*256*256+Data[18]*256+Data[17]);

            iGX = (UInt32)(Data[24]*256*256*256+Data[23]*256*256+Data[22]*256+Data[21]);
            iGY = (UInt32)(Data[28]*256*256*256+Data[27]*256*256+Data[26]*256+Data[25]);
            iGZ = (UInt32)(Data[32]*256*256*256+Data[31]*256*256+Data[30]*256+Data[29]);
            
            //处于发送寻北命令后状态
            if (iFlag == 3)
            {
                if (bFlag == 0x00)//寻北命令应答
                {
                    //tmNorth.Enabled = false;
                    this.Invoke(SetTimerEnable, tmNorth, false);//停止发送寻北
                    dtStart = DateTime.Now;//记录开始寻北时间
                    iFlag = 4; //接收寻北命令后返回的状态 
                    return 1; //返回一代表位置信心发送成功。
                }
                else
                {
                    //iFlag = 4; //寻北结束。
                    return 0; //代表位置信息发送失败。
                }
            }

            //寻北命令应答后
            if (iFlag == 4)
            {
                dTestQ = iQingJiao / 100;
                dTestF = iFangWei / 100;
                dTestH = iGunDong / 100;

                mtF.Value = dTestF;
                mtQ.Value = dTestQ;

                txtFW.Text = dTestF.ToString();
                txtQJ.Text = dTestQ.ToString();
                txtGDJ.Text = dTestH.ToString();

                if (bFlag == 0x00)//寻北过程应答
                {
                    iFlag = 4; //寻北没结束，状态。
                    return 1; //返回一代表位置信心发送成功。
                }
                else
                {
                    dtEnd = DateTime.Now;//记录开始寻北时间
                    txtTime.Text = (dtEnd - dtStart).TotalSeconds.ToString();
                    iFlag = 5; //寻北结束。
                    return 1; //代表位置信息发送失败。
                }
            }

            iFlag = 1;
            return 0;            
           
        }

        //接收串口数据,每次的响应消息是35个字节
        //iFlag = 1为发送位置信息，2为接收到位置信息返回，3 发送寻北信息，4 接收寻北信息返回
        private void serialPort_DataReceived(object sender, System.IO.Ports.SerialDataReceivedEventArgs e)
        {
            Byte[] Data = new Byte[35];
            serialPort.Read(Data, 0, 35);

            /*
            if ((CheckData(Data) == 0) && (iFlag == 1) )
            {
                SendPosition();
                return;
            }
            */
            if ((CheckData(Data) == 1) && (iFlag == 2)) //接收到位置信息后，可以发送寻北命令
            {
                this.Invoke(SetTimerEnable, tmNorth, true);//启动发送寻北命令定时器
                return;
            }

            if ((CheckData(Data) == 1) && (iFlag == 4)) //寻北应答帧收到
            {
               
                return;
            }

            if ((CheckData(Data) == 1) && (iFlag == 5))
            {
                mtF.Value = dTestF;
                mtQ.Value = dTestQ;

                txtFW.Text = dTestF.ToString();
                txtQJ.Text = dTestQ.ToString();
                txtGDJ.Text = dTestH.ToString();
                
                txtTime.Text = (dtEnd - dtStart).TotalSeconds.ToString();                
            }            
        }

        //窗口打开后，就发送位置信息，当位置信息发送成功，接收到返回值后，再发寻北命令
        private void InfoFrm_Load(object sender, EventArgs e)
        {
            iFlag = 1;
            serialPort.Open();
            //SendPosition();//发送位置信息
            tmParam.Enabled = true;//发送位置信息
           tmNorth.Enabled = false;
        }

        private void tmParam_Tick(object sender, EventArgs e)
        {
            if (iFlag  <  2) 
                SendPosition();
        }

        private void tmNorth_Tick(object sender, EventArgs e)
        {
            SendSearchNorth();
        }       
    }
}

